<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=5,IE=9" ><![endif]-->
<!DOCTYPE html>
<html>
<head>
    <title>Flowchart Maker &amp; Online Diagram Software</title>
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="Description" content="draw.io is free online diagram software for making flowcharts, process diagrams, org charts, UML, ER and network diagrams">
    <meta name="Keywords" content="diagram, online, flow chart, flowchart maker, uml, erd">
    <meta itemprop="name" content="draw.io - free flowchart maker and diagrams online">
	<meta itemprop="description" content="draw.io is a free online diagramming application  and flowchart maker . You can use it to create UML, entity relationship,
		org charts, BPMN and BPM, database schema and networks. Also possible are telecommunication network, workflow, flowcharts, maps overlays and GIS, electronic 
		circuit and social network diagrams.">
	<meta itemprop="image" content="https://lh4.googleusercontent.com/-cLKEldMbT_E/Tx8qXDuw6eI/AAAAAAAAAAs/Ke0pnlk8Gpg/w500-h344-k/BPMN%2Bdiagram%2Brc2f.png">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <link rel="canonical" href="https://www.draw.io">
    <script type="text/javascript">
		/**
		 * URL Parameters and protocol description are here:
		 *
		 * https://support.draw.io/pages/viewpage.action?pageId=12878136
		 *
		 * Parameters for developers:
		 *
		 * - dev=1: For developers only
		 * - test=1: For developers only
		 * - drawdev=1: For developers only
		 * - export=URL for export: For developers only
		 * - pages=1: For developers only
		 * - page=n: For developers only
		 * - ignoremime=1: For developers only (see DriveClient.js). Use Cmd-S to override mime.
		 * - createindex=1: For depelopers only (see etc/build/README)
		 * - filesupport=0: For developers only (see Editor.js in core)
		 * - savesidebar=1: For developers only (see Sidebar.js)
		 * - pages=1: For developers only (see Pages.js)
		 * - lic=email: For developers only (see LicenseServlet.java)
		 * --
		 * - networkshapes=1: For testing network shapes (temporary)
		 */
		var urlParams = (function()
		{
			var result = new Object();
			var params = window.location.search.slice(1).split('&');
			
			for (var i = 0; i < params.length; i++)
			{
				idx = params[i].indexOf('=');
				
				if (idx > 0)
				{
					result[params[i].substring(0, idx)] = params[i].substring(idx + 1);
				}
			}
			
			return result;
		})();
	</script>
    <link rel="alternate" type="application/rss+xml" title="RSS Feed for draw.io" href="http://blog.draw.io/feed/">
    <link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/plgmlhohecdddhbmmkncjdmlhcmaachm">
	<link rel="apple-touch-icon" sizes="57x57" href="images/apple-touch-icon-57x57.png">
	<link rel="apple-touch-icon" sizes="60x60" href="images/apple-touch-icon-60x60.png">
	<link rel="apple-touch-icon" sizes="72x72" href="images/apple-touch-icon-72x72.png">
	<link rel="apple-touch-icon" sizes="76x76" href="images/apple-touch-icon-76x76.png">
	<link rel="apple-touch-icon" sizes="114x114" href="images/apple-touch-icon-114x114.png">
	<link rel="apple-touch-icon" sizes="120x120" href="images/apple-touch-icon-120x120.png">
	<link rel="apple-touch-icon" sizes="144x144" href="images/apple-touch-icon-144x144.png">
	<link rel="apple-touch-icon" sizes="152x152" href="images/apple-touch-icon-152x152.png">
	<link rel="apple-touch-icon" sizes="180x180" href="images/apple-touch-icon-180x180.png">
	<link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32">
	<link rel="icon" type="image/png" href="images/favicon-194x194.png" sizes="194x194">
	<link rel="icon" type="image/png" href="images/favicon-96x96.png" sizes="96x96">
	<link rel="icon" type="image/png" href="images/android-chrome-192x192.png" sizes="192x192">
	<link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16">
	<link rel="manifest" href="images/manifest.json">
	<link rel="mask-icon" href="images/safari-pinned-tab.svg" color="#f18808">
	<meta name="msapplication-TileColor" content="#da532c">
	<meta name="msapplication-TileImage" content="images/mstile-144x144.png">
	<meta name="msapplication-config" content="images/browserconfig.xml">
	<meta name="theme-color" content="#f18808">
    <link rel="apple-touch-startup-image" href="images/logo-flat.png">
    <link rel="stylesheet" type="text/css" href="styles/grapheditor.css">
	<style type="text/css">
		body { overflow:hidden; }
		.geSidebarContainer .geTitle { color:#505050; }
		.geSidebarContainer .geTitle input {
			font-size:8pt;
			color:#606060;
		}
		.geBlock {
			z-index:-3;
			margin:100px;
			margin-top:40px;
			margin-bottom:30px;
			padding:20px;
		}
		.geBlock h1, .geBlock h2 {
			margin-top:0px;
			padding-top:0px;
		}
		.geEditor ::-webkit-scrollbar {
		    width:12px;
		    height:12px;
		}
		.geEditor ::-webkit-scrollbar-track {
			background:whiteSmoke;
			-webkit-box-shadow:inset 0 0 4px rgba(0,0,0,0.1);
		}
		.geEditor ::-webkit-scrollbar-thumb {
			background:#c5c5c5;
		    border-radius:10px;
			border:whiteSmoke solid 3px;
		}
		.geEditor ::-webkit-scrollbar-thumb:hover {
			background:#b5b5b5;
		}
		.geTemplate {
			border:1px solid transparent;
			display:inline-block;
			_display:inline;
			vertical-align:top;
			border-radius:3px;
			overflow:hidden;
			font-size:14pt;
			cursor:pointer;
			margin:5px;
		}
		.geFooterContainer div.geSocialFooter a {
			display:inline;
			padding:0px;
		}
		.geFooterContainer div.geSocialFooter a img {
			margin-top:10px;
			opacity:0.8;
		}
		.geFooterContainer div.geSocialFooter a img:hover {
			opacity:1;
		}
		#geFooterItem1 {
			background-color: #cdcdcd;
		}
		#geFooterItem1:hover {
			background-color: #b0b0b0;
		}		
		.geFooterContainer>div>img {
			opacity:0.5;
			background:#e5e5e5;
			border:1px solid transparent;
			cusor:pointer;
			margin-top:3px;
			margin-right:6px;
			position:absolute;
			right:4px;
			top:12px;
			padding:1px;
			cursor:pointer;
		}
		.geFooterContainer>div>img:hover {
			opacity: 1;
		}
		.geBlink {
		  animation: geBlinker 1s linear infinite;
		}
		@keyframes geBlinker {  
		  50% { opacity: 0.0; }
		}
	</style>
	<!-- Workaround for binary XHR in IE 9/10, see App.loadUrl -->
	<!--[if (IE 9)|(IE 10)]><!-->
		<script type="text/vbscript">
			Function mxUtilsBinaryToArray(Binary)
				Dim i
				ReDim byteArray(LenB(Binary))
				For i = 1 To LenB(Binary)
					byteArray(i-1) = AscB(MidB(Binary, i, 1))
				Next
				mxUtilsBinaryToArray = byteArray
			End Function
		</script>
	<!--<![endif]-->
	<script type="text/javascript">
		/**
		 * Synchronously adds scripts to the page.
		 */
		function mxscript(src, onLoad, id, dataAppKey)
		{
			if (onLoad != null)
			{
				var s = document.createElement('script');
				s.setAttribute('type', 'text/javascript');
				s.setAttribute('src', src);
				var r = false;
				
				if (id != null)
				{
					s.setAttribute('id', id);
				}
				
				if (dataAppKey != null)
				{
					s.setAttribute('data-app-key', dataAppKey);
				}
				
				s.onload = s.onreadystatechange = function()
				{
					if (!r && (!this.readyState || this.readyState == 'complete'))
					{
			      		r = true;
			      		onLoad();
					}
			  	};
			  	
			  	var t = document.getElementsByTagName('script')[0];
			  	t.parentNode.insertBefore(s, t);
			}
			else
			{
				document.write('<script src="' + src + '"' + ((id != null) ? ' id="' + id +'" ' : '') +
					((dataAppKey != null) ? ' data-app-key="' + dataAppKey +'" ' : '') + '></scr' + 'ipt>');
			}
		};

		/**
		 * Asynchronously adds scripts to the page.
		 */
		function mxinclude(src)
		{
			var g = document.createElement('script'); g.type = 'text/javascript'; g.async = true; g.src = src;
		    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(g, s);
		};

		// Checks for local storage and SVG support
		var isLocalStorage = false; // No local storage in sandstorm because of subdomains - typeof(localStorage) != 'undefined';

		var t0 = new Date();
	
		// Public global variables
		var SANDSTORM = true;
		var MAX_REQUEST_SIZE = 10485760;
		var MAX_AREA = 10000 * 10000;
	
		// CUSTOM_PARAMETERS - URLs for save and export
		var EXPORT_URL = 'https://exp.draw.io/ImageExport4/export';

		var SAVE_URL = 'save';
		var OPEN_URL = 'open';
		var PROXY_URL = 'proxy';

		// Paths and files
		var STENCIL_PATH = 'stencils';
		var SHAPES_PATH = 'shapes';
		var IMAGE_PATH = 'images';
		// Path for images inside the diagram
		var GRAPH_IMAGE_PATH = 'img';
		ICONFINDER_PATH = (navigator.userAgent.indexOf('MSIE') >= 0) ? 'iconfinder' : 'https://www.draw.io/iconfinder';

		// Used to request grapheditor/mxgraph sources in dev mode
		var mxDevUrl = document.location.protocol + '//devhost.jgraph.com/mxgraph2';

		// Used to request draw.io sources in dev mode
		var drawDevUrl = '';

		if (urlParams['drawdev'] == '1')
		{
			drawDevUrl = document.location.protocol + '//drawhost.jgraph.com/';
		}

		// Customizes export URL
		var ex = urlParams['export'];
		
		if (ex != null)
		{
			EXPORT_URL = ex;
		}

		urlParams['analytics'] = '0';
		urlParams['picker'] = '0';
		urlParams['gapi'] = '0';
		urlParams['db'] = '0';
		urlParams['od'] = '0';
		urlParams['embed'] = '1';

		// Changes paths for local development environment
		if (urlParams['dev'] == '1')
		{
			// Used to request draw.io sources in dev mode
			var drawDevUrl = '';

			if (urlParams['drawdev'] == '1')
			{
				drawDevUrl = document.location.protocol + '//drawhost.jgraph.com/';
			}
			
			mxscript(drawDevUrl + 'js/diagramly/Init.js');
			mxscript(geBasePath + '/Init.js');

			// Used to request grapheditor/mxgraph sources in dev mode
			var mxDevUrl = document.location.protocol + '//devhost.jgraph.com/mxgraph2';
			geBasePath = mxDevUrl + '/javascript/examples/grapheditor/www/js';
			mxBasePath = mxDevUrl + '/javascript/src';
			mxscript(mxBasePath + '/js/mxClient.js');

			// Adds all JS code that depends on mxClient. This indirection via Devel.js is
			// required in some browsers to make sure mxClient.js (and the files that it
			// loads asynchronously) are available when the code loaded in Devel.js runs.
			mxscript(drawDevUrl + 'js/diagramly/Devel.js');
			//mxscript(drawDevUrl + 'js/sandstorm/SandstormFile.js');
		}
		else
		{
			mxscript('js/app.min.js');
			//mxscript('js/sandstorm/SandstormFile.js');
		}
		
		// Loads JSON for older browsers
		if (typeof(JSON) == 'undefined')
		{
			mxscript('js/json/json2.min.js');
		}
		
		// Adds basic error handling
		window.onerror = function()
		{
			var status = document.getElementById('geStatus');
			
			if (status != null)
			{
				status.innerHTML = 'Page could not be loaded. Please try refreshing.';
			}
		};
	</script>
</head>
<body class="geEditor">
<div id="geInfo">
	<div class="geBlock" style="text-align:center;">
		<h3 id="geStatus">Loading... Please ensure JavaScript is enabled</h2>
	</div>
</div>
<script type="text/javascript">

(function()
{
	EditorUi.prototype.footerHeight = 0;

	EditorUi.prototype.initializeEmbedMode = function()
	{
		mxUtils.get('var/drawiodiagram.xml', mxUtils.bind(this, function(req)
		{
			if (req.getStatus() == 200)
			{
				mxUtils.get('.can-write', mxUtils.bind(this, function(req2)
				{
					var ssFile = new SandstormFile(this, req.getText(), null);

					if (req2.getText() == "false")
					{
						ssFile.editable = false;
					}
					
					this.spinner.stop();
					this.fileLoaded(ssFile);
					
				}), mxUtils.bind(this, function()
				{
					// No action, only failed to read the write status
				}));
			}
			else if (req.getStatus() == 404)
			{
				this.fileLoaded(null);
			}
			else
			{
				this.handleError(null, mxResources.get('errorLoadingFile'), reconnect);
			}
		}), mxUtils.bind(this, function()
		{
			this.handleError(null, mxResources.get('errorLoadingFile'), reconnect);
		}));
	};

	App.prototype.showSplash = function()
	{
		this.hideDialog();
		this.actions.get('new').funct();
	};

	App.prototype.createFile = function(title, data, libs, mode, done)
	{
		data = (data != null) ? data : this.emptyDiagramXml;
		
		var error = mxUtils.bind(this, function(resp)
		{
			if (resp == null && this.getCurrentFile() == null && this.dialog == null)
			{
				this.showSplash();
			}
			else if (resp != null)
			{
				this.handleError(resp);
			}
		});

		if (done != null)
		{
			done();
		}
	
		this.fileCreated(new SandstormFile(this, data, title), libs);
	};

	//////////////// Sandstorm File ///////////////////
	SandstormFile = function(ui, data, title)
	{
		DrawioFile.call(this, ui, data);
		
		this.title = title;
		this.editable = true;
	};

	mxUtils.extend(SandstormFile, DrawioFile);

	SandstormFile.prototype.isAutosave = function()	{ return true; };
	SandstormFile.prototype.getMode = function() { return App.MODE_DEVICE; };
	SandstormFile.prototype.getTitle = function() { return this.title; };
	SandstormFile.prototype.isRenamable = function() { return this.editable; };
	SandstormFile.prototype.isEditable = function() { return this.editable; };

	/**
	 *
	 */
	SandstormFile.prototype.save = function(revision, success, error)
	{
		this.saveAs(this.title, success, error);
	};

	/**
	 *
	 */
	SandstormFile.prototype.saveAs = function(title, success, error)
	{
		DrawioFile.prototype.save.apply(this, arguments);
		this.saveFile(this.title, null, success, error);
	};
	
	/**
	 *
	 */
	SandstormFile.prototype.saveFile = function(title, revision, success, error, unloading)
	{
		var data = this.getData();
		this.title = title;
		
		var request = new mxXmlRequest('var/drawiodiagram.xml', data, 'PUT');

		request.send(mxUtils.bind(this, function(req)
		{
			this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('allChangesSaved')));
		}), mxUtils.bind(this, function()
		{
			this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('unsavedChanges')));
		}));
		
		this.contentChanged();
		
		if (success != null)
		{
			success();
		}
	};
	//////////////// End Sandstorm File ///////////////////
	
	//////////////// Custom menu actions //////////////////
	


	//////////////// End custom menu actions //////////////////

	/**
	 * Main
	 */
 	App.prototype.enableLogging = false;
	
	App.main(function(ui)
	{
	 	ui.actions.get('save').visible = false;
	 	ui.actions.get('exit').visible = false;
	 	ui.actions.get('feedback').visible = false;
		
	 	// Changes support link in Help menu
	 	ui.actions.addAction('support...', function()
	 	{
	 		window.open('https://support.draw.io/display/DFS/draw.io+for+Sandstorm+Home');
	 	});
	});

// 	EditorUi.prototype.isExportToCanvas = function()
// 	{
// 		// LATER: Fix security error caused by foreignObjects in Safari for toDataUri (tainted canvas)
// 		return false;
// 	};

// 	// Loads and executes the plugins
// 	if (urlParams['offline'] != '1')
// 	{
// 		var plugins = mxSettings.getPlugins();

// 		if (plugins != null && plugins.length > 0 && urlParams['plugins'] != '0')
// 		{
// 			// Global entry point for plugins is Draw.loadPlugin. This is the only
// 			// long-term supported solution for access to the EditorUi instance.
// 			window.Draw = new Object();
// 			window.Draw.loadPlugin = function(callback)
// 			{
// 				callback(ui);
// 			};
			
// 			if (plugins.length == 1 && (plugins[0].charAt(0) == '/' ||
// 				plugins[0].indexOf(window.location.protocol + '//' + window.location.host) == 0))
// 			{
// 				mxscript(plugins[0]);
// 			}
// 			// Loads plugins asynchronously
// 			else if (mxUtils.confirm(mxResources.get('pluginWarning', [plugins.join('\n')]).replace(/\\n/g, '\n')))
// 			{
// 				for (var i = 0; i < plugins.length; i++)
// 				{
// 					mxscript(plugins[i]);
// 				}
// 			}
// 		}
// 	}
})();
</script>
</body>
</html>

